from tkinter import *
from time import clock, sleep

from shared.events import UserInput
from ui.abstract import AbstractUI

class TkinterUI(AbstractUI):

    def __init__(self, state, width=800, height=600):

        super(TkinterUI, self).__init__(state)

        #Create the window
        self.root = Tk()
        self.root.title(self._game_name + " (TkinterUI)")
        self.root.resizable(FALSE, FALSE)

        #Set up event bindings
        self.root.bind("<KeyPress>", self.key_down)
        self.root.protocol("WM_DELETE_WINDOW", self.quit_)

        #Create the gamne screen
        self.s = Canvas(self.root, width=width, height=height, bg = "black")
        self.s.pack()

        #Add the info and title
        self.s.create_text(width - 100, 50, text="pymaze", fill="white", font=("Times", "40"), anchor = CENTER)
        instructions = []
        for key, desc in self._get_key_help().items():
            instructions.append("[%s] : %s" %(key, desc))
        instructions.sort()
        lines = "INSTRUCTIONS\n" + "\n".join(instructions)

        self.s.create_text(width - 100, 125, text=lines, fill="white", font=("Times", "15"), anchor = N)


        #Initialize gloal variables
        self.state = state
        self.width = width
        self.height = height
        self.keys = []
        self.drawn_entities = {}
        self.hasQuit = False

        #Maze variables
        self.tileSizeX = int((self.width-200) // self.state.maze.sizeX)
        self.tileSizeY = int(self.height // self.state.maze.sizeY)
        self.vShift = (self.height % self.state.maze.sizeY) // 2

        #Load in resources
        self.res = {
            'wall': PhotoImage(file="res/wall.gif"),
            'player': PhotoImage(file="res/player.gif"),
            'enemy': PhotoImage(file="res/enemy.gif")
        }

        self.draw_maze()

    def poll(self):

        self.clock = clock()

        if self.hasQuit:
            self.root.destroy()
            yield UserInput("QUIT")
        else:
            for key in self.keys:
                e = self._get_event_from_char(key)
                if e is not None:
                    yield e
            self.keys = []

    def wait(self):

        run_time = clock() - self.clock

        sleep_time = (1 / self._frame_rate) - run_time

        if sleep_time > 0:
            sleep(sleep_time)

    def draw(self):

        self.draw_entity(self.state.player, "green")

        for enemy in self.state.enemies:
            self.draw_entity(enemy, "red")

        self.s.update()

    def draw_maze(self):

        for x in range(self.state.maze.sizeX):
            for y in range(self.state.maze.sizeY):
                if self.state.maze[x, y] == 0:
                    self.s.create_rectangle(x*self.tileSizeX, y*self.tileSizeY+self.vShift,
                                            x*self.tileSizeX+self.tileSizeX, y*self.tileSizeY+self.tileSizeY+self.vShift,
                                            fill = "Black")
                else:
                    self.s.create_rectangle(x*self.tileSizeX, y*self.tileSizeY+self.vShift,
                                            x*self.tileSizeX+self.tileSizeX, y*self.tileSizeY+self.tileSizeY+self.vShift,
                                            fill = "White")

        for x, y in self.state.maze.exits:
            self.s.create_polygon(x*self.tileSizeX, (y+1)*self.tileSizeY,
                                  (x+0.5)*self.tileSizeX, y*self.tileSizeY,
                                  (x+1)*self.tileSizeX, (y+1)*self.tileSizeY,
                                  fill = "blue")

        self.s.update()

    def draw_entity(self, entity, color):

        loc = entity.location

        tileX = loc[0] * self.tileSizeX
        tileY = (loc[1] * self.tileSizeY) + self.vShift

        if entity in self.drawn_entities:
            self.s.coords(self.drawn_entities[entity], tileX, tileY,
                          tileX+self.tileSizeX,
                          tileY+self.tileSizeY+self.vShift)
        else:
            self.drawn_entities[entity] = self.s.create_oval(tileX, tileY, tileX+self.tileSizeX, tileY+self.tileSizeY+self.vShift, fill = color)

    #EVENTS
    def key_down(self, e):

        self.keys.append(e.char)

    def quit_(self):

        self.hasQuit = True
